﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using ezCloud.Data;
using System.Text;
using System.Reflection;
using ezCloud.Api.Models;
using System.Data.Linq.Mapping;
using System.Collections;
using System.Data;
using System.Data.SqlClient;
using System.Globalization;

namespace ezCloud.Api.Common
    {
    public class Utilities
    {
        ezCloudDataContext context = new ezCloudDataContext();
        public static string FullyQualifiedApplicationPath
        {
            get
            {
                //Return variable declaration
                var appPath = string.Empty;

                //Getting the current context of HTTP request
                var context = HttpContext.Current;

                //Checking the current context content
                if (context != null)
                {
                    //Formatting the fully qualified website url/name
                    appPath = string.Format("{0}://{1}{2}{3}",
                                            context.Request.Url.Scheme,
                                            context.Request.Url.Host,
                                            context.Request.Url.Port == 80
                                                ? string.Empty
                                                : ":" + context.Request.Url.Port,
                                            context.Request.ApplicationPath);
                }

                if (!appPath.EndsWith("/"))
                    appPath += "/";

                return appPath;
            }
        }
        public static void AddLog(string logName, string logId, string logContent)
        {
            ezCloudDataContext context = new ezCloudDataContext();

            var currentUser = Common.UserUtitily.getUserProfile();
            var ul = new UserLogs();
            var request = HttpContext.Current.Request;
            ul.Ip = request.UserHostAddress;
            ul.Url = request.Headers["Url"] != null ? request.Headers["Url"] : "/";
            if (currentUser != null)
            {
                ul.UserId = currentUser.UserId;
                ul.UserName = currentUser.UserName;
                ul.HotelId = currentUser.HotelId;
            }
            ul.CreatedDate = DateTime.Now;
            ul.ObjectKey = logId;
            ul.CategoryName = logName;
            ul.Content = logContent;
            context.UserLogs.InsertOnSubmit(ul);
            context.SubmitChanges();

        }
        public static string GetObjectContent(object obj)
        {
            StringBuilder sb = new StringBuilder();
            Type type = obj.GetType();
            foreach (PropertyInfo propertyInfo in type.GetProperties())
                {
                if (propertyInfo.CanRead)
                    {
                    var name = propertyInfo.Name;
                    var value = propertyInfo.GetValue(obj, null) == null ? "" : propertyInfo.GetValue(obj, null).ToString();
                    sb.AppendLine(name + ":" + value);
                    }
                }
            return obj.ToString();
        }
        public static string GetDifferentContent(object obj, object obj2)
        {
            StringBuilder sb = new StringBuilder();
            Type type = obj.GetType();
            foreach (PropertyInfo propertyInfo in type.GetProperties())
                {
                if (propertyInfo.CanRead)
                    {
                    var name = propertyInfo.Name;
                    var value = propertyInfo.GetValue(obj, null) == null ? "" : propertyInfo.GetValue(obj, null).ToString();
                    var value2 = propertyInfo.GetValue(obj2, null) == null ? "" : propertyInfo.GetValue(obj2, null).ToString();
                    if (value != value2)
                        {
                        sb.AppendLine(name + ":" + value2 + "=>" + value);
                        }
                    }
                }
            return sb.ToString();
        }

        public static string convertToUnSign(string s)
        {
            string stFormD = s.Normalize(NormalizationForm.FormD);
            StringBuilder sb = new StringBuilder();
            for (int ich = 0; ich < stFormD.Length; ich++)
            {
                System.Globalization.UnicodeCategory uc = System.Globalization.CharUnicodeInfo.GetUnicodeCategory(stFormD[ich]);
                if (uc != System.Globalization.UnicodeCategory.NonSpacingMark)
                {
                    sb.Append(stFormD[ich]);
                }
            }
            sb = sb.Replace('Đ', 'D');
            sb = sb.Replace('đ', 'd');
            return (sb.ToString().Normalize(NormalizationForm.FormD));
        }

        public static DataTable GetAvailableRooms(DateTime fromDate, DateTime toDate)
        {
            var currentTime = DateTime.Now;
            var user = Common.UserUtitily.getUserProfile();
            var context = new ezCloudDataContext();

            
            DataSet ds = new DataSet();
            DataTable AvailableRooms = new DataTable();
            string ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["EzCloudConnectionString"].ToString();
            using (SqlConnection conn = new SqlConnection(ConnectionString))
            {
                SqlCommand sqlComm = new SqlCommand("dbo.GetAvailableRooms", conn);
                sqlComm.Parameters.AddWithValue("@HotelId", user.HotelId);
                sqlComm.Parameters.AddWithValue("@FromDate", fromDate);
                sqlComm.Parameters.AddWithValue("@Date", toDate);
                sqlComm.CommandType = CommandType.StoredProcedure;
                SqlDataAdapter da = new SqlDataAdapter();
                da.SelectCommand = sqlComm;
                da.Fill(AvailableRooms);
            }
            return AvailableRooms;
        }


        public static DataTable GetAvailableRoomsByRoomType(DateTime fromDate, DateTime toDate)
        {
            var currentTime = DateTime.Now;
            var user = Common.UserUtitily.getUserProfile();
            var context = new ezCloudDataContext();


            DataSet ds = new DataSet();
            DataTable AvailableRoomsByRoomType = new DataTable();
            string ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["EzCloudConnectionString"].ToString();
            using (SqlConnection conn = new SqlConnection(ConnectionString))
            {
                SqlCommand sqlComm = new SqlCommand("dbo.GetAvailableRoomsByRoomType", conn);
                sqlComm.Parameters.AddWithValue("@HotelId", user.HotelId);
                sqlComm.Parameters.AddWithValue("@FromDate", fromDate);
                sqlComm.Parameters.AddWithValue("@Date", toDate);
                sqlComm.CommandType = CommandType.StoredProcedure;
                SqlDataAdapter da = new SqlDataAdapter();
                da.SelectCommand = sqlComm;
               
                //a.Fill(t);
                da.Fill(AvailableRoomsByRoomType);
                //hotelRelatedTables = ds.Tables[0];

            }
            return AvailableRoomsByRoomType;
        }

        public static NumberFormatInfo GetCurrencyFormatProviderSymbolDecimals(string currencyCode)
        {
            if (String.IsNullOrWhiteSpace(currencyCode))
                return NumberFormatInfo.CurrentInfo;


            var currencyNumberFormat = (from culture in CultureInfo.GetCultures(CultureTypes.SpecificCultures)
                                        let region = new RegionInfo(culture.LCID)
                                        where String.Equals(region.ISOCurrencySymbol, currencyCode,
                                                            StringComparison.InvariantCultureIgnoreCase)
                                        select culture.NumberFormat).First();

            //Need to Clone() a shallow copy here, because GetInstance() returns a read-only NumberFormatInfo
            var desiredNumberFormat = (NumberFormatInfo)NumberFormatInfo.GetInstance(CultureInfo.CurrentCulture).Clone();
            desiredNumberFormat.CurrencyDecimalDigits = currencyNumberFormat.CurrencyDecimalDigits;
            //desiredNumberFormat.CurrencySymbol = currencyNumberFormat.CurrencySymbol;
            desiredNumberFormat.CurrencySymbol = "";
            return desiredNumberFormat;
        }
        public static DataTable GetRoomAvailabilityMatrix(DateTime fromDate, DateTime toDate)
        {
            var currentTime = DateTime.Now;
            var user = Common.UserUtitily.getUserProfile();
            var context = new ezCloudDataContext();


            DataSet ds = new DataSet();
            DataTable RoomAvailabilityMatrix = new DataTable();
            string ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["EzCloudConnectionString"].ToString();
            using (SqlConnection conn = new SqlConnection(ConnectionString))
            {
                SqlCommand sqlComm = new SqlCommand("dbo.RoomAvailabilityMatrix", conn);
                sqlComm.Parameters.AddWithValue("@HotelId", user.HotelId);
                sqlComm.Parameters.AddWithValue("@FromDate", fromDate);
                sqlComm.Parameters.AddWithValue("@Date", toDate);
                sqlComm.CommandType = CommandType.StoredProcedure;
                SqlDataAdapter da = new SqlDataAdapter();
                da.SelectCommand = sqlComm;

                //a.Fill(t);
                da.Fill(RoomAvailabilityMatrix);
                //hotelRelatedTables = ds.Tables[0];

            }
            return RoomAvailabilityMatrix;
        }
        public static DataTable GetRoomAvailabilityMatrix(int hoteId,DateTime fromDate, DateTime toDate)
        {
            var currentTime = DateTime.Now;
          
            DataSet ds = new DataSet();
            DataTable RoomAvailabilityMatrix = new DataTable();
            string ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["EzCloudConnectionString"].ToString();
            using (SqlConnection conn = new SqlConnection(ConnectionString))
            {
                SqlCommand sqlComm = new SqlCommand("dbo.RoomAvailabilityMatrix", conn);
                sqlComm.Parameters.AddWithValue("@HotelId", hoteId);
                sqlComm.Parameters.AddWithValue("@FromDate", fromDate);
                sqlComm.Parameters.AddWithValue("@Date", toDate);
                sqlComm.CommandType = CommandType.StoredProcedure;
                SqlDataAdapter da = new SqlDataAdapter();
                da.SelectCommand = sqlComm;

                //a.Fill(t);
                da.Fill(RoomAvailabilityMatrix);
                //hotelRelatedTables = ds.Tables[0];

            }
            return RoomAvailabilityMatrix;
        }
        public static DataTable GetRoomSalesForecast(DateTime fromDate, DateTime toDate)
        {
            var currentTime = DateTime.Now;
            var user = Common.UserUtitily.getUserProfile();
            var context = new ezCloudDataContext();


            DataSet ds = new DataSet();
            DataTable returnData = new DataTable();
            string ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["EzCloudConnectionString"].ToString();
            using (SqlConnection conn = new SqlConnection(ConnectionString))
            {
                SqlCommand sqlComm = new SqlCommand("dbo.RoomSalesForecast", conn);
                sqlComm.Parameters.AddWithValue("@HotelId", user.HotelId);
                sqlComm.Parameters.AddWithValue("@FromDate", fromDate);
                sqlComm.Parameters.AddWithValue("@Date", toDate);
                sqlComm.CommandType = CommandType.StoredProcedure;
                SqlDataAdapter da = new SqlDataAdapter();
                da.SelectCommand = sqlComm;
                da.Fill(returnData);
            }
            return returnData;
        }
        public static string GetFullName(string firstName, string lastName)
        {
            string FullName = "";
            FullName = firstName + " " + lastName;
            if (FullName.Length > 50) FullName = FullName.Substring(0, 50);
            return FullName;
        }

        public static bool CheckRoomIsCheckout(int ReservationRoomId)
        {
            bool result = false;
            var context = new ezCloudDataContext();
            var currentClientUser = Common.UserUtitily.getUserProfile();
            var currentRR = context.ReservationRooms.Where(rr => rr.HotelId == currentClientUser.HotelId && rr.ReservationRoomId == ReservationRoomId && rr.BookingStatus == "CHECKOUT").FirstOrDefault();
            if (currentRR != null)
            {
                result = true;
            }
            return result;
        }
    }


    public class CascadingDeleteHelper
    {
        public void Delete(object entity, Func<object, bool> beforeDeleteCallback)
        {
            ezCloudDataContext context = new ezCloudDataContext();
            //if (!(entity is BusinessEntity))
            //{
            //    throw new ArgumentException("Argument is not a valid BusinessEntity");
            //}

            if (beforeDeleteCallback == null || beforeDeleteCallback(entity))
            {
                Type currentType = entity.GetType();
                foreach (var property in currentType.GetProperties())
                {
                    var attribute = property
                        .GetCustomAttributes(true)
                        .Where(a => a is AssociationAttribute)
                        .FirstOrDefault();

                    if (attribute != null)
                    {
                        AssociationAttribute assoc = attribute as AssociationAttribute;
                        if (!assoc.IsForeignKey)
                        {
                            var propertyValue = property.GetValue(entity, null);
                            if (propertyValue != null && propertyValue is IEnumerable)
                            {
                                IEnumerable relations = propertyValue as IEnumerable;
                                List<object> relatedEntities = new List<object>();

                                foreach (var relation in relations)
                                {
                                    relatedEntities.Add(relation);
                                }
                                relatedEntities.ForEach(e => Delete(e, beforeDeleteCallback));
                            }
                        }
                    }
                }

                context.GetTable(currentType).DeleteOnSubmit(entity);
                context.SubmitChanges();
            }
        }
    }



}
